package com.adnaan.backend.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.adnaan.backend.common.exception.ServicesException;
import com.adnaan.backend.entity.SysPermission;
import com.adnaan.backend.entity.SysUser;
import com.adnaan.backend.entity.dto.OptionDto;
import com.adnaan.backend.mapper.SysUserMapper;
import com.adnaan.backend.service.SysUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * author: adnaan
 * create: 2025-01-05 15:40
 * Description:
 */
@Service
@Slf4j
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
    @Override
    public List<OptionDto> getRoles(Long id) {
        return baseMapper.getRolesByUserId(id);
    }

    @Override
    public void insertRoles(Long id, List<String> roleIds) {
        baseMapper.insertRoleIds(id, roleIds);
    }

    @Override
    public void deleteRoles(Long id) {
        baseMapper.deleteRoleIds(id);
    }

    @Override
    public List<String> listRolesByUserId(String userId) {
        return baseMapper.getRoleCodeByUserId(Long.valueOf(userId));
    }

    @Override
    public List<String> listPermissionsByRoleCode(String roleCode) {
        return baseMapper.listPermissionsByRoleCode(roleCode);
    }

    @Override
    public List<JSONObject> listMenuByUserId() {
        List<SysPermission> permissions = baseMapper.listMenuByUserId(StpUtil.getLoginIdAsLong());
        // 使用Stream API进行过滤和排序
        List<SysPermission> parentPermissions = permissions.stream()
                .filter(permission -> permission.getType() == 0)
                .sorted(Comparator.comparing(SysPermission::getSort))
                .toList();
        List<SysPermission> childPermissions = permissions.stream()
                .filter(permission -> permission.getType() != 0)
                .sorted(Comparator.comparing(SysPermission::getSort))
                .toList();
        // 使用Map来快速查找父菜单
        Map<Long, JSONObject> parentMap = new HashMap<>();
        for (SysPermission parent : parentPermissions) {
            JSONObject parentJsonObject = convertToJsonObject(parent);
            if (parentJsonObject.get("children") == null) {
                parentJsonObject.putOnce("children", new JSONArray()); // 初始化children数组
            }
            parentMap.put(parent.getId(), parentJsonObject);
        }
        List<JSONObject> data = new ArrayList<>(parentMap.values());
        for (SysPermission child : childPermissions) {
            Long parentId = child.getParentId().longValue();
            if (parentMap.containsKey(parentId)) {
                parentMap.get(parentId).getJSONArray("children").add(convertToJsonObject(child));
            } else {
                // 处理找不到父菜单的情况，可以根据需要记录日志或抛出异常
                log.warn("No parent menu found for child permission with id: " + child.getId());
                throw new ServicesException("出现未关联菜单");
            }
        }
        return data;
    }

    @Override
    public void setLastLoginTime(Long id) {
        baseMapper.setLastLoginTime(id);
    }

    /**
     * 转换为前端路由格式（将SysPermission转换为JSONObject）
     *
     * @param sysPermission
     * @return
     */
    private JSONObject convertToJsonObject(SysPermission sysPermission) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.putOnce("id", sysPermission.getId());
        jsonObject.putOnce("name", sysPermission.getNameEn().replaceAll(" ", ""));
        jsonObject.putOnce("path", sysPermission.getPath());

        JSONObject meta = new JSONObject();
        JSONObject title = new JSONObject();
        title.putOnce("zh_CN", sysPermission.getName());
        title.putOnce("en_US", sysPermission.getNameEn());
        meta.putOnce("title", title);
        meta.putOnce("orderNo", sysPermission.getSort());
        meta.putOnce("icon", sysPermission.getIcon());

        if (sysPermission.getType() == 0) {
            jsonObject.putOnce("component", "LAYOUT");
            jsonObject.putOnce("children", new JSONArray());
        } else {
            if (sysPermission.getOuterChain() == 1) {
                jsonObject.putOnce("component", "IFrame");
                meta.putOnce("frameSrc", sysPermission.getCode());
            } else {
                jsonObject.putOnce("component", sysPermission.getComponents());
            }
        }

        jsonObject.putOnce("meta", meta);
        return jsonObject;
    }
}
